﻿using Sys.Core.Models.Dto;
using Sys.Core.Models.Queries;
using Sys.Core.Models.VO;
using Sys.Core.Providers;
using MiniFox;
using MiniFox.Components;
using MiniFox.Infrastructure;
using MiniFox.Platform.Applications;
using MiniFox.Platform.Applications.Auth;
using MiniFox.Platform.Exceptions;
using MiniFox.Utility;
using System.Reflection;

namespace Sys.Core.Services
{
    public class AppService : ApiServiceBase, IAppService
    {
        public AppService(SystemPrincipal principal) : base(principal)
        {
        }

        [AutoWired]
        public IApplicationProvider Provider { get; set; }

        protected virtual string GenerateSecretKey()
        {
            string newKey = Tools.GenerateRandomHashCode(32);
            return newKey;
        }

        public ResultObject<IEnumerable<ApplicationVo>> Query(PagedQueryObject<AppQuery> request)
        {
            return this.Provider.Query(request);
        }

        public ApplicationVo Item(string appId)
        {
            return this.Provider.GetApplication(appId);
        }

        public ApplicationVo Create(ApplicationDto application)
        {
            string newKey = GenerateSecretKey();
            if (!this.Provider.CreateApplication(application, newKey))
                return null;

            return this.Provider.GetApplication(application.ApplicationID);
        }

        public ApplicationVo Update(ApplicationDto application)
        {
            if (!this.Provider.UpdateApplication(application))
                return null;

            return this.Provider.GetApplication(application.ApplicationID);
        }

        public void Delete(string appId)
        {
            if (!this.Provider.DeleteApplication(appId))
                throw new PlatformException("ERR_OperateFail");
        }

        public void Toggle(string appId)
        {
            if (!this.Provider.ToggleApplication(appId))
                throw new PlatformException("ERR_OperateFail");
        }

        public ModuleVo CreateModule(ModuleDto module)
        {
            module.ModuleID = SequenceGUID.NewGUID();
            if (!this.Provider.CreateModule(module))
                return null;

            return this.GetModule(module.ModuleID);
        }

        public ModuleVo UpdateModule(ModuleDto module)
        {
            if (!this.Provider.UpdateModule(module))
                return null;

            return this.GetModule(module.ModuleID);
        }

        public void DeleteModule(params string[] modules)
        {
            this.Provider.DeleteModule(modules);
        }

        public ModuleVo GetModule(string moduleId)
        {
            return this.Provider.GetModule(moduleId);
        }

        public ResultObject<IEnumerable<ModuleVo>> QueryModules(PagedQueryObject<ModuleQuery> query)
        {
            return this.Provider.QueryModules(query);
        }

        public string GetSecretKey(string appId)
        {
            return this.Provider.GetSecretKey(appId);
        }

        public string NewSecretKey(string appId)
        {
            string newKey = GenerateSecretKey();
            this.Provider.SetSecretKey(appId, newKey);
            return newKey;
        }

        public IEnumerable<ModuleActionVo> GetModuleActions(string moduleId)
        {
            return this.Provider.GetModuleActions(moduleId);
        }

        public ModuleActionVo CreateModuleAction(ModuleActionDto moduleAction)
        {
            moduleAction.ActionID = SequenceGUID.NewGUID();
            if (!this.Provider.CreateModuleAction(moduleAction))
                return null;

            return this.GetModuleAction(moduleAction.ActionID);
        }

        public ModuleActionVo UpdateModuleAction(ModuleActionDto moduleAction)
        {
            if (!this.Provider.UpdateModuleAction(moduleAction))
                return null;

            return this.GetModuleAction(moduleAction.ActionID);
        }

        public void DeleteModuleAction(params string[] moduleActions)
        {
            this.Provider.DeleteModuleAction(moduleActions);
        }

        public ModuleActionVo GetModuleAction(string actionId)
        {
            return this.Provider.GetModuleAction(actionId);
        }

    }
}